package com.tn.rtdata.jmx;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.tn.rtdata.FillHeartbeat;
import com.tn.rtdata.FillIdentity;
import com.tn.rtdata.FillListener;

/**
 * An implementation of <code>SessionInfoMXBean</code> that references the fill and session cache in order to return session information.
 */
public class FillInfo extends AbstractInfo implements FillInfoMXBean
{
  private Map<FillIdentity, com.tn.rtdata.FillInfo<?, ?>> fillInfoCache;
  private Map<FillIdentity, FillHeartbeat> fillHeartbeatCache;
  private Map<String, Map<com.tn.rtdata.FillIdentity, FillListener>> sessionCache;

  /**
   * Creates a new <code>FillInfo</code> initialized with the <code>fillCache</code> and <code>sessionCache</code>.
   */
  public FillInfo(
    Map<FillIdentity, com.tn.rtdata.FillInfo<?, ?>> fillInfoCache,
    Map<FillIdentity, FillHeartbeat> fillHeartbeatCache,
    Map<String, Map<com.tn.rtdata.FillIdentity, FillListener>> sessionCache
  )
  {
    this.fillInfoCache = fillInfoCache;
    this.fillHeartbeatCache = fillHeartbeatCache;
    this.sessionCache = sessionCache;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public List<com.tn.rtdata.jmx.Fill> getFills()
  {
    Map<FillIdentity, List<String>> sessions = indexSessions(sessionCache);

    List<com.tn.rtdata.jmx.Fill> fills = new ArrayList<com.tn.rtdata.jmx.Fill>();

    for (FillIdentity fillIdentity : fillInfoCache.keySet())
    {
      FillHeartbeat fillHeartbeat = fillHeartbeatCache.get(fillIdentity);

      fills.add(
        new com.tn.rtdata.jmx.Fill(
          fillHeartbeat != null ? fillHeartbeat.getControlProcessId() : null,
          fillIdentity.getName(),
          convertFillParameters(fillIdentity.getParameters()),
          sessions.get(fillIdentity)
        )
      );
    }

    return fills;
  }

  /**
   * Creates an index of the sessions by fill identity.
   */
  private Map<FillIdentity, List<String>> indexSessions(Map<String, Map<FillIdentity, FillListener>> sessionCache)
  {
    Map<FillIdentity, List<String>> sessions = new HashMap<FillIdentity, List<String>>();

    for (String sessionId : sessionCache.keySet())
    {
      for (FillIdentity fillIdentity : sessionCache.get(sessionId).keySet())
      {
        List<String> sessionsForFill = sessions.get(fillIdentity);

        if (sessionsForFill == null)
        {
          sessionsForFill = new ArrayList<String>();
          sessions.put(fillIdentity, sessionsForFill);
        }

        sessionsForFill.add(sessionId);
      }
    }

    return sessions;
  }
}
